#include "BasicBase64Tools.h"

extern "C"
{
	#include "./libsrc/cdecode.h"
	#include "./libsrc/cencode.h"
};

#include "BasicTranscode.h"
#include <Windows.h>

namespace utility
{
	BasicBase64Tools::BasicBase64Tools(void)
	{
	}

	BasicBase64Tools::~BasicBase64Tools(void)
	{
	}

	/*BasicBase64Tools& BasicBase64Tools::operator=( const BasicBase64Tools& object )
	{
		return *this;
	}*/

	int BasicBase64Tools::EncodeBase64( const TCHAR* inbuf, int inLen, TCHAR* outbuf, int outLen )
	{
#ifdef UNICODE
		std::string strIn;
		utility::BasicTranscode::Unicode_to_ANSI(inbuf, strIn);
		char* szBuf = new char[outLen+2];
		ZeroMemory(szBuf, outLen+2);

		int nRet = EncodeBase64Ex(strIn.c_str(), strIn.length(), szBuf, outLen );

		std::wstring strValue;
		utility::BasicTranscode::ANSI_to_Unicode(szBuf, outLen, strValue );
		memcpy_s( outbuf, outLen, strValue.c_str(), strValue.length());
		delete[] szBuf;

		return nRet ;
#else
		return EncodeBase64Ex(inbuf, inLen, outbuf, outLen);
#endif
	}

	int BasicBase64Tools::DecodeBase64( const TCHAR* inbuf, TCHAR* outbuf, int outLen )
	{
#ifdef UNICODE
		std::string strIn;
		utility::BasicTranscode::Unicode_to_ANSI(inbuf, strIn);
		char* szBuf = new char[outLen+2];
		ZeroMemory(szBuf, outLen+2);

		int nRet = DecodeBase64Ex(strIn.c_str(), szBuf, outLen );

		std::wstring strValue;
		utility::BasicTranscode::ANSI_to_Unicode(szBuf, outLen, strValue );
		memcpy_s( outbuf, outLen, strValue.c_str(), strValue.length());
		delete[] szBuf;

		return nRet ;
#else
		return DecodeBase64Ex(inbuf, outbuf, outLen);
#endif
	}

	int BasicBase64Tools::EncodeBase64Ex( const void* input, int inputLength, char* output, int outputBufferLength )
	{
		int bufferSize = 2 * inputLength;
		char* buffer = (char*)malloc(bufferSize);
		memset(buffer, 0, bufferSize);

		base64_encodestate state;
		base64_init_encodestate(&state);
		int r1 = base64_encode_block(static_cast<const char*>(input), inputLength, buffer, &state);
		int r2 = base64_encode_blockend(buffer+ r1, &state);

		int dataUsed = r1 + r2;
		memset(output, 0, outputBufferLength);
		int cp = dataUsed < outputBufferLength ? dataUsed : outputBufferLength - 1;
		memcpy(output, buffer, cp);

		free(buffer);
		return cp;
	}

	int BasicBase64Tools::DecodeBase64Ex( const char* input, void* output, int outputBufferLength )
	{
		int bufferSize = strlen(input) + 1;
		char* buffer = (char*)malloc(bufferSize);
		memset(buffer, 0, bufferSize);
		base64_decodestate state;
		base64_init_decodestate(&state);
		int r1 = base64_decode_block(input, bufferSize - 1, buffer, &state);

		memset(output, 0, outputBufferLength);
		int cp = r1 < outputBufferLength ? r1 : outputBufferLength - 1;
		memcpy(output, buffer, cp);
		free(buffer);
		return cp;
	}

	
}
